﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ext.Net;
using System.ComponentModel;
using System.Xml.Serialization;
using Newtonsoft.Json;
using System.Data.Linq;
using System.Xml;
using System.Xml.Xsl;
using System.Reflection;
using System.IO;
using Enterprise.Resource;
using Enterprise.Settings;
using System.Xml.Linq;
using System.Web;

namespace Enterprise.Web.Controls
{
    [DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)]
    public partial class XGridPanel : GridPanel
    {
        private Store store;
        private Ext.Net.JsonReader reader;
        private int _GridID;
        private int _PageSize;
        private Assembly _assembly;

        PagingToolbar pagingToolbar;
        Hidden FormatType;
        Button btnExportXML;
        Button btnExportExcel;
        Button btnExportCSV;
        Button btnAddNew;

        bool _EnableDownloadXML;
        bool _EnableDownloadExcel;
        bool _EnableDownloadCSV;

        public XGridPanel()
        {            
            this.InitDefaultValue();
            this.BuildStyle();
            this.BuildItems();
            this.BuildStore();
        }

        #region public properties
        public int GridID
        {
            get
            {
                return this._GridID;
            }
            set
            {
                if ((this._GridID != value))
                {
                    this._GridID = value;
                    this.SetRowCommand();
                }
            }
        }
        public int PageSize
        {
            get
            {
                return this._PageSize;
            }
            set
            {
                if ((this._PageSize != value))
                {
                    this._PageSize = value;
                }
            }
        }
        public bool EnableDownloadXML
        {
            get
            {
                return this._EnableDownloadXML;
            }
            set
            {
                if ((this._EnableDownloadXML != value))
                {
                    this._EnableDownloadXML = value;
                }
            }
        }
        public bool EnableDownloadExcel
        {
            get
            {
                return this._EnableDownloadExcel;
            }
            set
            {
                if ((this._EnableDownloadExcel != value))
                {
                    this._EnableDownloadExcel = value;
                }
            }
        }
        public bool EnableDownloadCSV
        {
            get
            {
                return this._EnableDownloadCSV;
            }
            set
            {
                if ((this._EnableDownloadCSV != value))
                {
                    this._EnableDownloadCSV = value;
                }
            }
        }
        #endregion

        #region private methods
        private void InitDefaultValue()
        {
            _assembly = Assembly.GetExecutingAssembly();
            _EnableDownloadXML = false;
            _EnableDownloadExcel = false;
            _EnableDownloadCSV = false;
            _PageSize = 24;
            this.store = new Store();
            this.reader = new Ext.Net.JsonReader();
            btnAddNew = new Button(Resource.Resource.btnAddNew.ToString());
            btnAddNew.Visible = false;
            btnExportXML = new Button(Resource.Resource.btnExportXML.ToString());
            btnExportExcel = new Button(Resource.Resource.btnExportExcel.ToString());
            btnExportCSV = new Button(Resource.Resource.btnExportCSV.ToString());
        }

        private void BuildStyle()
        {
            this.TrackMouseOver = true;
            this.StripeRows = true;
        }
       
        private void BuildItems()
        {
            FormatType = new Hidden();
            FormatType.ID = "FormatType";
            this.Items.Add(FormatType);           
        }

        private void BuidlBottomBar()
        {
            pagingToolbar = new PagingToolbar();
            pagingToolbar.PageSize = _PageSize;            
            this.BottomBar.Add(pagingToolbar);
        }

        private void BuildTopBar()
        {
            Toolbar toolbar = new Toolbar();
            
            btnAddNew.Icon = Icon.Add;
            btnAddNew.IconAlign = IconAlign.Left;
            
            toolbar.Items.Add(btnAddNew);
            toolbar.Items.Add(new ToolbarFill());
    
            btnExportXML.Icon = Icon.PageCode;
            btnExportXML.Visible = _EnableDownloadXML;
            toolbar.Items.Add(btnExportXML);
          
            btnExportExcel.Icon = Icon.PageExcel;
            btnExportExcel.Visible = _EnableDownloadExcel;
            toolbar.Items.Add(btnExportExcel);
            
            btnExportCSV.Icon = Icon.PageAttach;
            btnExportCSV.Visible = _EnableDownloadCSV;
            toolbar.Items.Add(btnExportCSV);

            this.TopBar.Add(toolbar);
        }

        private void InitLogic()
        {
            
        }

        private void BuildStore()
        {
           // this.Store.Primary.
            
            this.reader.IDProperty = "ID";
            this.store.Reader.Add(reader);
            this.store.SubmitData += StoMainSource_Submit;
            this.store.DirectEventConfig.IsUpload = true;
            this.Store.Add(this.store);
        }

        private void SetRowCommand()
        {
            string xmlContent = Resource.Resource.ResourceManager.GetObject(EnterpriseConstant.RESOURCE_GRIDCOMMAND_XML).ToString();
            XDocument xdoc = XDocument.Parse(xmlContent);
            if (xdoc != null)
            {
                var newdataset =
                    (from grid in xdoc.Descendants("Grid")
                     where grid.Attribute("ID").Value.Equals(_GridID.ToString())
                     select new
                     {
                         id = grid.Attribute("ID"),
                         command = (from commands in grid.Elements("Commands").Elements("CommandID")
                                    select new List<string>()
                                  {
                                      commands.Value
                                  }).ToList()
                     }).SingleOrDefault();

                List<string> commandList = new List<string>();

                foreach (var item in newdataset.command)
                {
                    foreach (var item1 in item)
                    {
                        commandList.Add(item1.ToString());
                    }
                }

                var rowcommands =
                    (from commands in xdoc.Descendants("Command")
                     where commandList.Contains(commands.Element("ID").Value.ToString())
                     select new
                     {
                         ID = commands.Element("ID"),
                         Name = commands.Element("Name"),
                         Type = commands.Element("Type"),
                         Icon = commands.Element("Icon"),
                     }).ToList();


                ColumnModel cm = this.ColumnModel;
                CommandColumn commandColumn = new CommandColumn();
                commandColumn.Width = 40;
                GridCommand gridCommand = new GridCommand();
                gridCommand.Icon = Icon.ArrowDown;

                btnAddNew.Visible = false;
                foreach (var item in rowcommands)
                {
                    EnterpriseConstant.GridCommandType gct = (EnterpriseConstant.GridCommandType)Enum.Parse(typeof(EnterpriseConstant.GridCommandType), item.Type.Value.ToString());
                    switch (gct)
                    {
                        case EnterpriseConstant.GridCommandType.Add:
                            if (item.ID.Value.ToString() == EnterpriseConstant.GRIDCOMMAND_ADD)
                            {
                                btnAddNew.Visible = true;
                                break;
                            }
                            else 
                                goto case EnterpriseConstant.GridCommandType.View;                            
                        case EnterpriseConstant.GridCommandType.Edit:
                        case EnterpriseConstant.GridCommandType.Delete:
                        case EnterpriseConstant.GridCommandType.View:
                            MenuCommand menuCommand = new MenuCommand();
                            menuCommand.Icon = (Icon)Enum.Parse(typeof(Icon), item.Icon.Value.ToString());
                            menuCommand.Text = item.Name.Value.ToString();
                            menuCommand.CommandName = Resource.Resource.commandNameEdit.ToString();
                            gridCommand.Menu.Items.Add(menuCommand);
                            break;
                        default:
                            break;
                    }
                }
                commandColumn.Commands.Add(gridCommand);
                cm.Columns.Add(commandColumn);
            }
        }

        #endregion

        #region public method
        // must call after config grid
        public void BuildGrid()
        {
            this.SelectionModel.Add(new CheckboxSelectionModel
            {
                MoveEditorOnEnter = false,
                SingleSelect = true
            });
            this.BuildTopBar();
            this.BuidlBottomBar();
            //this.BuildStore();
            
            this.InitLogic();                        
        }

        public void AddGridColumn(string pIndexName, string pHeaderName)
        {
            //columnID will automatically create with prefix "col" with HeaderName
            this.ColumnModel.Columns.Add(new Column { ColumnID = "col" + pHeaderName, DataIndex = pIndexName, Header = pHeaderName });
        }

        public void AddGridColumn(string pIndexName, string pHeaderName, int pColumnWidth)
        {
            this.ColumnModel.Columns.Add(new Column { ColumnID = "col" + pIndexName, DataIndex = pIndexName, Header = pHeaderName, Width = pColumnWidth });
        }

        public void AddGridDateColumn(string pIndexName, string pHeaderName, string pDateFormat)
        {
            this.ColumnModel.Columns.Add(new DateColumn { ColumnID = "col" + pHeaderName, DataIndex = pIndexName, Header = pHeaderName, Format = pDateFormat });
        }

        public void AddGridDateColumn(string pIndexName, string pHeaderName, string pDateFormat, int pColumnWidth)
        {
            this.ColumnModel.Columns.Add(new DateColumn { ColumnID = "col" + pHeaderName, DataIndex = pIndexName, Header = pHeaderName, Format = pDateFormat, Width = pColumnWidth });
        }

        public void AddRecordField(RecordField field)
        {
            this.reader.Fields.Add(field);
        }

        public void SetDataSource(IEnumerable<object> datasource)
        {
            //if (Page.IsPostBack){}
            this.store.DataSource = datasource;
            this.store.DataBind();
        }

        public void SetAutoExpandColumn(string pColumnName)
        {
            //must specify columnID.
            this.AutoExpandColumn = "col" + pColumnName;
        }

        #endregion

        #region overide methods
        protected override void OnBeforeClientInit(Observable sender)
        {
            base.OnBeforeClientInit(sender);
            btnExportXML.Listeners.Click.Handler =  string.Format("{0}.setValue('xml');{1}.submitData(false);nomask=true;", this.FormatType.ClientID, this.ClientID);
            btnExportExcel.Listeners.Click.Handler = string.Format("{0}.setValue('xls');{1}.submitData(false);nomask=true;", this.FormatType.ClientID, this.ClientID);
            btnExportCSV.Listeners.Click.Handler = string.Format("{0}.setValue('csv');{1}.submitData(false);nomask=true;", this.FormatType.ClientID, this.ClientID);
        }
        #endregion

        #region protected methods
        protected void StoMainSource_Submit(object sender, StoreSubmitDataEventArgs e)
        {
            string format = this.FormatType.Value.ToString();
            string strDownloadFileName = this.Title;
            XmlNode xml = e.Xml;
            Ext.Net.X.AddScript("Ext.net.Mask.hide();");
            this.Page.Response.Clear();
            switch (format)
            {
                case "xml":
                    string strXml = xml.OuterXml;
                    this.Page.Response.AddHeader("Content-Disposition", "attachment; filename=submittedData.xml");
                    this.Page.Response.AddHeader("Content-Length", strXml.Length.ToString());
                    this.Page.Response.ContentType = "application/xml";
                    this.Page.Response.Write(strXml);
                    break;
                case "xls":
                    this.Page.Response.ContentType = "application/vnd.ms-excel";
                    this.Page.Response.AddHeader("Content-Disposition", "attachment; filename=submittedData.xls");
                    XslCompiledTransform xtExcel = new XslCompiledTransform();
                    xtExcel.Load((new Uri("pack://application:,,,/Enterprise;component/Excel.xsl")).AbsolutePath);
                    xtExcel.Transform(xml, null, this.Page.Response.OutputStream);
                    break;
                case "csv":
                    this.Page.Response.ContentType = "application/octet-stream";
                    this.Page.Response.AddHeader("Content-Disposition", "attachment; filename=submittedData.csv");
                    XslCompiledTransform xtCsv = new XslCompiledTransform();
                    xtCsv.Load(this.Page.Server.MapPath("~/Enterprise/Resource/Csv.xsl"));
                    xtCsv.Transform(xml, null, this.Page.Response.OutputStream);
                    break;
            }
            this.Page.Response.End();
        }
        #endregion        
    }
    
    
}
